package com.dycong.common.IO.socket.SSL;

import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.security.*;
import java.security.cert.CertificateException;

/**
 * Created by dycong on 2017/3/27.
 */
public class TestSSLSocketServer {
    private static String PATH = "F:\\keytool\\sslsocket.keystore";
    private static char[] PASSWORD = "CerPassWord".toCharArray();

    public static void main(String[] args) {
        boolean flag = true;
        SSLContext context = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(new FileInputStream(PATH), PASSWORD);
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
            keyManagerFactory.init(keyStore, PASSWORD);
            KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
            context = SSLContext.getInstance("SSL");
            context.init(keyManagers, null, null);
/*
KeyManager[] 第一个参数是授权的密钥管理器，用来授权验证。TrustManager[]第二个是被授权的证书管理器，用来验证服务器端的证书。
第三个参数是一个随机数值，可以填写null。如果只是服务器传输数据给客户端来验证，就传入第一个参数就可以，客户端构建环境就传入第二个参数。

双向认证的话，就同时使用两个管理器。
也可以选择使用单向认证，这种情况下client侧不需要提供证书: server侧只需要自己的keystore文件，不需要truststore文件client侧不需要自己的keystore文件，只需要truststore文件
（其中包含server的公钥）。此外server侧需要在创建SSLServerSocket之后设定不需要客户端证书：setNeedClientAuth(false)
 */
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        SSLServerSocketFactory ssf = (SSLServerSocketFactory) context.getServerSocketFactory();
        try {
            SSLServerSocket sss = (SSLServerSocket) ssf.createServerSocket(8000);

            System.out.println("server listening port 8000");
            while (flag) {
                Socket socket = sss.accept();
                System.out.println("wait client...");
                OutputStream out = socket.getOutputStream();
                out.write("hello".getBytes());
                out.close();
                socket.close();
            }
            sss.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {

        }
    }

}
